package com.jeomo.common.core.util;

import cn.hutool.core.lang.UUID;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.common.comm.ResponseMessage;
import com.aliyun.oss.model.PutObjectResult;
import com.jeomo.common.core.config.AliConfig;
import com.jeomo.common.core.result.CommonResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.InputStream;

/**
 * aliOss上传助手
 *
 * @author崔贺
 */
@Component
@Lazy
public class AliOssUtils {

    Logger logger = LoggerFactory.getLogger(AliOssUtils.class);

    @Resource
    AliConfig aliConfig;

    /**
     * 专门负责上传文件到 OSS 服务器的工具方法
     *
     * @param inputStream  要上传的文件的输入流
     * @param originalName 要上传的文件的原始文件名
     * @return 包含上传结果以及上传的文件在 OSS 上的访问路径
     */
    public CommonResult<String> upload(
            InputStream inputStream,
            String originalName) {
        logger.debug("aliOss配置 endpoint ：" + aliConfig.getEndPoint());
        logger.debug("aliOss配置 accessKeyId ：" + aliConfig.getAccessKeyId());
        logger.debug("aliOss配置 accessKeySecret ：" + aliConfig.getAccessKeySecret());
        logger.debug("aliOss配置 bucketName ：" + aliConfig.getBucketName());
        logger.debug("aliOss配置 bucketDomain ：" + aliConfig.getBucketDomain());

        OSS ossClient = new OSSClientBuilder().build(aliConfig.getEndPoint(), aliConfig.getAccessKeyId(), aliConfig.getAccessKeySecret());

        // 创建 OSSClient 实例。
        // 生成上传文件的目录
//        String folderName = new SimpleDateFormat("yyyyMMdd").format(new Date());
//         /*生成上传文件在 OSS 服务器上保存时的文件名
//         原始文件名： xxx.jpg
//         生成文件名： xxxxxxx.jpg
//         使用 UUID 生成文件主体名称*/
        String fileMainName = UUID.randomUUID().toString().replace("-", "");
//        // 从原始文件名中获取文件扩展名
        String extensionName = originalName.substring(originalName.lastIndexOf("."));
//        // 使用目录、 文件主体名称、 文件扩展名称拼接得到对象名称
        String objectName = fileMainName + extensionName;
        try {
            // 调用 OSS 客户端对象的方法上传文件并获取响应结果数据
            PutObjectResult putObjectResult = ossClient.putObject(aliConfig.getBucketName(), objectName,
                    inputStream);
            // 从响应结果中获取具体响应消息
            ResponseMessage responseMessage = putObjectResult.getResponse();
            // 根据响应状态码判断请求是否成功
            if (responseMessage == null) {
                // 拼接访问刚刚上传的文件的路径
                String ossFileAccessPath = aliConfig.getBucketDomain() + "/" + objectName;
                // 当前方法返回成功
                return CommonResult.success(ossFileAccessPath);
            } else {
                // 获取响应状态码
                int statusCode = responseMessage.getStatusCode();
                // 如果请求没有成功， 获取错误消息
                String error = responseMessage.getErrorResponseAsString();
                // 当前方法返回失败
                String errorMessage = " 错 误 消 息 = " + error;
                return CommonResult.failure(statusCode, errorMessage);
            }
        } catch (Exception e) {
            e.printStackTrace();
            // 当前方法返回失败
            return CommonResult.failure(e.getMessage());
        } finally {
            if (ossClient != null) {
                // 关闭 OSSClient。
                ossClient.shutdown();
            }
        }
    }

    public Boolean delete(String path) {
        logger.debug("aliOss配置 endpoint ：" + aliConfig.getEndPoint());
        logger.debug("aliOss配置 accessKeyId ：" + aliConfig.getAccessKeyId());
        logger.debug("aliOss配置 accessKeySecret ：" + aliConfig.getAccessKeySecret());
        logger.debug("aliOss配置 bucketName ：" + aliConfig.getBucketName());
        logger.debug("aliOss配置 bucketDomain ：" + aliConfig.getBucketDomain());

        // 创建OSSClient实例。
        OSS ossClient = new OSSClientBuilder().build(aliConfig.getEndPoint(), aliConfig.getAccessKeyId(), aliConfig.getAccessKeySecret());
        //获取需要删除的文件名split[1]
        String[] split = path.split(aliConfig.getBucketDomain() + "/");
        // 删除文件。如需删除文件夹，请将ObjectName设置为对应的文件夹名称。如果文件夹非空，则需要将文件夹下的所有object删除后才能删除该文件夹。
        String fileName = split[1];
        boolean found = ossClient.doesObjectExist(aliConfig.getBucketName(), fileName);
        if (found) {
            ossClient.deleteObject(aliConfig.getBucketName(), fileName);
            return true;
        }
        // 关闭OSSClient。
        ossClient.shutdown();
        return false;
    }

}
